<template>
  <div style="height: 100%">
    <el-card style="height: 100%;width: 15%;float: left">
      <el-menu style="width: 100%"
        default-active="2"
        class="el-menu-vertical-demo">
        <el-menu-item index="1" @click="showAppPage">
          <i class="el-icon-menu"></i>
          <span slot="title">Apps</span>
        </el-menu-item>
        <el-menu-item index="2" @click="showServiceListPage">
          <i class="el-icon-menu"></i>
          <span slot="title">Choreography</span>
        </el-menu-item>
        <el-menu-item index="3" @click="showRunTime">
          <i class="el-icon-document"></i>
          <span slot="title">runtime</span>
        </el-menu-item>
      </el-menu>
    </el-card>
    <div id="apps" style="height: 100%;width:85%;float: right" v-show="showApps">
      <div>
        <el-button type="primary" style="margin-left: 10%;margin-top: 3%" size="medium" @click="addApps">Add App</el-button>
      </div>
      <div style="margin-top: 2%">
        <el-select v-model="appType" placeholder="请选择" size="medium" style="width: 150px;margin-left: 10%">
          <el-option
            v-for="item in appTypes"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
        <el-input v-model="searchAppInput" placeholder="请输入内容" size="medium" style="width: 40%"></el-input>
        <el-button type="primary" size="medium" icon="el-icon-search" style="margin-left: 2%" @click="researchAppsByType">Refresh</el-button>
        <el-table
          :data="appInfos"
          stripe
          border
          style="width: 80%;margin-left: 10%;margin-top: 5%" size="medium">
          <el-table-column
            prop="type"
            label="Type"
            width="180">
          </el-table-column>
          <el-table-column
            prop="name"
            label="Name"
            width="180">
          </el-table-column>
          <el-table-column
            prop="label"
            label="Label">
          </el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button
                size="mini"
                @click="editApp(scope.row)">编辑</el-button>
              <el-button
                size="mini"
                type="danger"
                @click="deleteApp(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
<!--        @current-change="handleCurrentChange" :current-page="currentPage4"-->
        <el-pagination
          @size-change="handleSizeChange"


          :page-sizes="[100, 200, 300, 400]"
          :page-size="100"
          layout="total, sizes, prev, pager, next, jumper"
          :total="400" style="float: right;margin-right: 10%">
        </el-pagination>
      </div>
    </div>
    <div id="appDetail" style="height: 100%;width:85%;float: right" v-show="showAppsDetail">
      <div>
        <el-button type="primary" style="margin-left: 10%;margin-top: 3%" size="mini" @click="showAppPage">< Add Application</el-button>
      </div>
      <el-tabs :tab-position="tabPosition" v-model="appTabName" style="margin-left: 10%;margin-top: 5%;height: 80%">
        <el-tab-pane label="Interface" name="Interface">
          <div style="margin-left: 10%;margin-top: 5%">
            Name *
            <el-input v-model="applicationName" size="medium" placeholder="service name" style="width: 40%;margin-left: 5%"></el-input>
          </div>
          <div style="margin-left: 10%;margin-top: 2%">
            Listening Type *
            <el-select v-model="listenType" placeholder="请选择" style="margin-left: 5%">
              <el-option
                v-for="item in listenTypes"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </div>
          <div style="margin-left: 10%;margin-top: 2%">
            <el-tabs type="border-card" style="width: 80%">
              <el-tab-pane label="Code">Code Infos</el-tab-pane>
              <el-tab-pane label="Describe">Description</el-tab-pane>
              <el-tab-pane label="Label">label infos</el-tab-pane>
            </el-tabs>
          </div>
          <el-button type="primary" size="medium" style="float: right;margin-right: 18%;margin-top: 3%">Save</el-button>
        </el-tab-pane>
        <el-tab-pane label="Script" name="Script">
          <div style="margin-left: 10%;margin-top: 5%">
            Name *
            <el-input v-model="scriptName" size="medium" placeholder="script name" style="width: 40%;margin-left: 5%"></el-input>
          </div>
          <div style="margin-left: 10%;margin-top: 2%">
            <el-tabs type="border-card" style="width: 80%">
              <el-tab-pane label="Code">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="scriptCode">
                </el-input>
              </el-tab-pane>
              <el-tab-pane label="Describe">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="scriptDescribe">
                </el-input>
              </el-tab-pane>
              <el-tab-pane label="Label">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="scriptLabel">
                </el-input>
              </el-tab-pane>
            </el-tabs>
          </div>
          <el-button type="primary" size="medium" style="float: right;margin-right: 18%;margin-top: 3%" @click="saveScript">Save</el-button>
        </el-tab-pane>
        <el-tab-pane label="Source" name="Source">
          <div style="margin-left: 10%;margin-top: 5%">
            Name *
            <el-input v-model="sourceName" size="medium" placeholder="source name" style="width: 40%;margin-left: 5%"></el-input>
          </div>
          <div style="margin-left: 10%;margin-top: 2%">
            <el-tabs type="border-card" style="width: 80%">
              <el-tab-pane label="Code">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="sourceCode">
                </el-input>
              </el-tab-pane>
              <el-tab-pane label="Describe">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="sourceDescribe">
                </el-input>
              </el-tab-pane>
              <el-tab-pane label="Label">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="sourceLabel">
                </el-input>
              </el-tab-pane>
            </el-tabs>
          </div>
          <el-button type="primary" size="medium" style="float: right;margin-right: 18%;margin-top: 3%" @click="saveSource">Save</el-button>
        </el-tab-pane>
        <el-tab-pane label="Sink" name="Sink">
          <div style="margin-left: 10%;margin-top: 5%">
            Name *
            <el-input v-model="sinkName" size="medium" placeholder="sink name" style="width: 40%;margin-left: 5%"></el-input>
          </div>
          <div style="margin-left: 10%;margin-top: 2%">
            <el-tabs type="border-card" style="width: 80%">
              <el-tab-pane label="Code">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="sinkCode">
                </el-input>
              </el-tab-pane>
              <el-tab-pane label="Describe">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="sinkDescribe">
                </el-input>
              </el-tab-pane>
              <el-tab-pane label="Label">
                <el-input
                  type="textarea"
                  autosize
                  placeholder="请输入内容"
                  v-model="sinkLabel">
                </el-input>
              </el-tab-pane>
            </el-tabs>
          </div>
          <el-button type="primary" size="medium" style="float: right;margin-right: 18%;margin-top: 3%" @click="saveSink">Save</el-button>
        </el-tab-pane>
      </el-tabs>
    </div>
    <div id="serviceList" style="height: 100%;width: 85%;float: right" v-show="showServiceList">
      <div>
        <el-button type="primary" style="margin-left: 10%;margin-top: 3%" size="medium" @click="turnToCreateServicePage">create Service</el-button>
      </div>
      <el-input v-model="inputServiceName" size="medium" placeholder="service name" style="width: 40%;margin-left: 10%;margin-top: 2%"></el-input>
      <el-button type="primary" size="medium" icon="el-icon-search" style="margin-left: 2%" @click="researchServiceByName">Refresh</el-button>
      <el-table
        :data="serviceInfos"
        stripe
        border
        style="width: 80%;margin-left: 10%;margin-top: 5%" size="medium">
        <el-table-column
          prop="name"
          label="Name"
          width="180">
        </el-table-column>
        <el-table-column
          prop="process"
          label="Process"
          width="280">
        </el-table-column>
        <el-table-column
          prop="operate"
          label="Operate">
        </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button
              size="mini"
              @click="editService(scope.row)">编辑</el-button>
            <el-button
              size="mini"
              type="danger"
              @click="deleteService(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        @size-change="handleSizeChange"


        :page-sizes="[100, 200, 300, 400]"
        :page-size="100"
        layout="total, sizes, prev, pager, next, jumper"
        :total="400" style="float: right;margin-right: 10%">
      </el-pagination>
    </div>
    <div id="serviceDetail" style="height: 100%;width:85%;float: right" v-show="showServiceDetail">
      <div style="height: 30%">
        <div>
          <el-button type="primary" style="margin-left: 10%;margin-top: 3%" size="mini" @click="showServiceListPage">< create service</el-button>
        </div>
        <el-input style="width: 80%;margin-left: 10%;margin-top: 2%;"
          type="textarea"
          :rows="5"
          placeholder="请输入内容"
          v-model="textarea">
        </el-input>
      </div>
      <div style="height: 70%">
        <a-layout class="container">
          <a-layout-sider
            width="300"
            theme="light"
            class="select-area">
            <a-row>
              <a-checkable-tag v-model="tag.checked0" @change="toggleNodeShow0" class="tag">工具</a-checkable-tag>
              <div align="center">
                <a-list
                  :grid="{ gutter: 8, column: 1 }"
                  v-if="tag.toolShow">
                  <a-list-item>
                    <a-button-group>
                      <a-button
                        v-for="(tool, index) in field.tools"
                        :key="index"
                        :icon="tool.icon"
                        :type="currentTool.type == tool.type ? 'primary': 'default'"
                        @click="selectTool(tool.type)">
                      </a-button>
                    </a-button-group>
                  </a-list-item>
                </a-list>
              </div>
            </a-row>
            <a-row>
              <a-checkable-tag v-model="tag.checked1" @change="toggleNodeShow1" class="tag">Source</a-checkable-tag>
              <div align="center">
                <a-list
                  :grid="{ gutter: 8, column: 2 }"
                  v-if="tag.commonNodeShow">
                  <a-list-item v-for="(asource, index) in alistSource" :key="index">
                    <div class="node-item" :type="asource.type" :belongto ="asource.nodeName">
                      <a-icon :component="asource.icon" /> {{ asource.nodeName }}
                    </div>
                  </a-list-item>
                </a-list>
              </div>
            </a-row>
            <a-row>
              <a-checkable-tag v-model="tag.checked2" @change="toggleNodeShow2" class="tag">Function</a-checkable-tag>
              <div align="center">
                <a-list
                  :grid="{ gutter: 8, column: 2 }"
                  v-if="tag.highNodeShow">
                  <a-list-item v-for="(afunction, index) in alistFunction" :key="index">
                    <div class="node-item" :type="afunction.type" :belongto ="afunction.nodeName">
                      <a-icon :component="afunction.icon" /> {{ afunction.nodeName }}
                    </div>
                  </a-list-item>
                </a-list>
              </div>
            </a-row>
            <a-row>
              <a-checkable-tag v-model="tag.checked3" @change="toggleNodeShow3" class="tag">Sink</a-checkable-tag>
              <div align="center">
                <a-list
                  :grid="{ gutter: 8, column: 2 }"
                  v-if="tag.laneNodeShow">
                  <a-list-item v-for="(asink, index) in alistSink" :key="index" >
                    <div class="node-item" :type="asink.type" :belongto ="asink.nodeName">
                      <a-icon :component="asink.icon" /> {{ asink.nodeName }}
                    </div>
                  </a-list-item>
                </a-list>
              </div>
            </a-row>
          </a-layout-sider>
          <a-layout>
            <a-layout-header class="header-option">
              <a-tooltip title="保存流程" placement="bottom">
                <a-button @click="saveFlow" class="header-option-button" size="small" icon="save">save</a-button>
              </a-tooltip>
              <a-popconfirm title="确认要重新绘制吗？" placement="bottom" okText="确认" cancelText="取消" @confirm="clear">
                <a-tooltip title="重新绘制" placement="bottom">
                  <a-button class="header-option-button" size="small" icon="delete"></a-button>
                </a-tooltip>
              </a-popconfirm>
              <a-tooltip :title="flowData.config.showGridText" placement="bottom">
                <a-button
                  @click="toggleShowGrid"
                  class="header-option-button"
                  size="small"
                  :icon="flowData.config.showGridIcon">
                </a-button>
              </a-tooltip>
              <a-tooltip title="设置" placement="bottom">
                <a-button @click="setting" class="header-option-button" size="small" icon="setting"></a-button>
              </a-tooltip>
              <a-popconfirm
                title="请选择帮助项："
                placement="bottom"
                okType="default"
                okText="快捷键大全"
                @confirm="shortcutHelper">
                <a-icon slot="icon" type="question-circle-o" style="color: red" />
                <a-tooltip title="帮助" placement="bottom">
                  <a-button class="header-option-button" size="small" icon="book"></a-button>
                </a-tooltip>
              </a-popconfirm>
              <a-tooltip title="退出" placement="bottom">
                <a-button @click="exit" class="header-option-button" size="small" icon="logout"></a-button>
              </a-tooltip>
            </a-layout-header>
            <a-layout-content class="content">
              <flow-area
                ref="flowArea"
                :browserType="browserType"
                :flowData="flowData"
                :select.sync="currentSelect"
                :selectGroup.sync="currentSelectGroup"
                :plumb="plumb"
                :currentTool="currentTool"
                @findNodeConfig="findNodeConfig"
                @selectTool="selectTool"
                @getShortcut="getShortcut"
                @saveFlow="saveFlow">
              </flow-area>
              <vue-context-menu
                :contextMenuData="linkContextMenuData"
                @deleteLink="deleteLink">
              </vue-context-menu>
            </a-layout-content>
          </a-layout>
          <a-layout-sider
            width="350"
            theme="light"
            class="attr-area"
            @mousedown.stop="loseShortcut">
            <flow-attr :plumb="plumb" :flowData="flowData" :select.sync="currentSelect"></flow-attr>
          </a-layout-sider>
        </a-layout>

        <setting-modal ref="settingModal"></setting-modal>
        <shortcut-modal ref="shortcutModal"></shortcut-modal>
        <test-modal ref="testModal" @loadFlow="loadFlow"></test-modal>
      </div>
    </div>

  </div>

</template>

<script>
	import jsplumb from 'jsplumb'
	import { tools, commonNodes, highNodes, laneNodes } from './config/basic-node-config.js'
	import { flowConfig } from './config/args-config.js'
	import { startSvg, endSvg, commonSvg, freedomSvg, gatewaySvg, eventSvg, childFlowSvg, xLaneSvg, yLaneSvg, lanePoolSvg } from './config/basic-icon-config.js'
	import $ from 'jquery'
	import 'jquery-ui/ui/widgets/draggable'
	import 'jquery-ui/ui/widgets/droppable'
	import 'jquery-ui/ui/widgets/resizable'
	import html2canvas from 'html2canvas'
	import canvg from 'canvg'
	import { ZFSN } from './util/ZFSN.js'
	import FlowArea from './modules/FlowArea'
	import FlowAttr from './modules/FlowAttr'
	import SettingModal from './modules/SettingModal'
	import ShortcutModal from './modules/ShortcutModal'
	import UsingDocModal from './modules/UsingDocModal'
	import TestModal from './modules/TestModal'

	export default {
		name: 'vfd',
		components: {
			jsplumb,
			flowConfig,
			html2canvas,
			canvg,
			FlowArea,
			FlowAttr,
			SettingModal,
			ShortcutModal,
			UsingDocModal,
			TestModal,
			StartIcon: { template: startSvg },
			EndIcon: { template: endSvg },
			CommonIcon: { template: commonSvg },
			FreedomIcon: { template: freedomSvg },
			GatewayIcon: { template: gatewaySvg },
			EventIcon: { template: eventSvg },
			ChildFlowIcon: { template: childFlowSvg },
			XLaneIcon: { template: xLaneSvg },
			YLaneIcon: { template: yLaneSvg },
			LanePoolIcon: { template: lanePoolSvg }
		},
    created(){
      const that = this;
      that.findAllSources();
      that.findAllFunctions();
      that.findAllSinks();
    },
		mounted () {
      const that = this;
      that.dealCompatibility();
      that.initNodeSelectArea();
      that.initJsPlumb();
      that.listenShortcut();
      that.initFlow();
      that.listenPage();
		},
		data () {
			return {
        serviceId:0,
			  appId:0,
        addOrUpdateService:'',
			  addOrUpdateApp:'',
        appTabName:'Interface',
			  alistSink:[],
        alistFunction:[],
        alistSource:[],
        scriptLabel:'',
        scriptDescribe:'',
        scriptCode:'',
        scriptName:'',
        sourceLabel:'',
        sourceDescribe:'',
        sourceCode:'',
        sourceName:'',
        sinkLabel:'',
        sinkDescribe:'',
        sinkCode:'',
        sinkName:'',
        listenType:'',
        listenTypes:[
          {
            value: 'Value1',
            label: 'Value1'
          }
        ],
        applicationName:'',
        tabPosition:'left',
        showAppsDetail:false,
        appInfos:[],
        searchAppInput:'',
        appType:'All Types',
        appTypes:[
          {
            value: 'All Types',
            label: 'All Types'
          },{
            value: 'Interface',
            label: 'Interface'
          },{
            value: 'Script',
            label: 'Script'
          },{
            value: 'Source',
            label: 'Source'
          },{
            value: 'Sink',
            label: 'Sink'
          }
        ],
        showApps:false,
        showServiceList:false,
        showServiceDetail:false,
        serviceInfos:[],
        inputServiceName:'',
        textarea: '',
				tag: {
					checked0: true,
					checked1: true,
					checked2: true,
					checked3: true,
					toolShow: true,
					commonNodeShow: true,
					highNodeShow: true,
					laneNodeShow: true
				},
				browserType: 3,
				plumb: {},
				field: {
					tools: tools,
					commonNodes: commonNodes,
					highNodes: highNodes,
					laneNodes: laneNodes
				},
				flowData: {
					nodeList: [],
					linkList: [],
					attr: {
            name:''
					},
					config: {
						showGrid: true,
						showGridText: '隐藏网格',
						showGridIcon: 'eye'
					},
					status: flowConfig.flowStatus.CREATE,
					remarks: []
				},
				currentTool: {
					type: 'drag',
					icon: 'drag',
					name: '拖拽'
				},
				currentSelect: {},
				currentSelectGroup: [],
				activeShortcut: true,
				linkContextMenuData: flowConfig.contextMenu.link,

			}
		},
		methods: {
      editService(row){
        this.addOrUpdateService = "update";
        this.showApps = false;
        this.showAppsDetail = false;
        this.showServiceDetail = true;
        this.showServiceList = false;
        this.initNodeSelectArea();
        this.loadFlow(row.uinfo);
        this.serviceId = row.id;
      },
      deleteService(row){
        this.$confirm('确认要删除该节点吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.axios.post("api/service/delete/"+row.id).then(reslut=>{
            this.researchServiceByName();
            this.$message({
              type: 'success',
              message: '删除成功!'
            });
          }).catch(error=>{
            this.$message({
              type: 'error',
              message: '删除失败!'
            });
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      },
      editApp(row){
        this.addOrUpdateApp = "update";
        this.showApps = false;
        this.showAppsDetail = true;
        this.showServiceDetail = false;
        this.showServiceList = false;
        this.appId = row.id;
        this.scriptLabel='';
        this.scriptDescribe='';
        this.scriptCode='';
        this.scriptName='';
        this.sourceLabel='';
        this.sourceDescribe='';
        this.sourceCode='';
        this.sourceName='';
        this.sinkLabel='';
        this.sinkDescribe='';
        this.sinkCode='';
        this.sinkName='';
        if(row.type ==="SCRIPT"){
          this.appTabName = "Script";
          this.scriptName = row.name;
          this.scriptCode = row.code;
          this.scriptDescribe = row.describeInfo;
          this.scriptLabel = row.label;
        }else if(row.type ==="SOURCE"){
          this.appTabName = "Source";
          this.sourceName = row.name;
          this.sourceCode = row.code;
          this.sourceDescribe = row.describeInfo;
          this.sourceLabel = row.label;
        }else if(row.type ==="SINK"){
          this.appTabName = "Sink";
          this.sinkName = row.name;
          this.sinkCode = row.code;
          this.sinkDescribe = row.describeInfo;
          this.sinkLabel = row.label;
        }
      },
      deleteApp(row){
        this.$confirm('确认要删除该节点吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.axios.post("api/app/delete/"+row.id).then(reslut=>{
            this.researchAppsByType();
            this.$message({
              type: 'success',
              message: '删除成功!'
            });
          }).catch(error=>{
            this.$message({
              type: 'error',
              message: '删除失败!'
            });
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      },
      saveScript(){
        if(this.addOrUpdateApp === 'add'){
          let queryParams = {param:{name:this.scriptName,code:this.scriptCode,describe:this.scriptDescribe,label:this.scriptLabel}};
          this.axios.post("api/app/add/script",queryParams).then(result =>{
            this.$message({
              message: "添加成功",
              type: 'success'
            });
          }).catch(err=>{
            this.$message.error("添加出错:"+err);
          })
        }else if(this.addOrUpdateApp === 'update'){
          let params = {code:this.scriptCode,describeInfo:this.scriptDescribe,label:this.scriptLabel,id:this.appId};
          this.axios.post("api/app/update",params).then(result =>{
            if(result.data === "更新成功"){
              this.$message({
                message: "更新成功",
                type: 'success'
              });
            }else{
              this.$message.error("更新失败");
            }
          }).catch(error=>{
            this.$message.error("更新出错:"+error);
          })
        }
      },
      saveSource(){
        if(this.addOrUpdateApp === 'add'){
          let queryParams = {param:{name:this.sourceName,code:this.sourceCode,describe:this.sourceDescribe,label:this.sourceLabel}};
          this.axios.post("api/app/add/source",queryParams).then(result =>{
            this.$message({
              message: "添加成功",
              type: 'success'
            });
          }).catch(err=>{
            this.$message.error("添加出错:"+err);
          })
        }else if(this.addOrUpdateApp === 'update'){
          let params = {code:this.sourceCode,describeInfo:this.sourceDescribe,label:this.sourceLabel,id:this.appId};
          this.axios.post("api/app/update",params).then(result =>{
            if(result.data === "更新成功"){
              this.$message({
                message: "更新成功",
                type: 'success'
              });
            }else{
              this.$message.error("更新失败");
            }
          }).catch(error=>{
            this.$message.error("更新出错:"+error);
          })
        }
      },
      saveSink(){
        if(this.addOrUpdateApp === 'add'){
          let queryParams = {param:{name:this.sinkName,code:this.sinkCode,describe:this.sinkDescribe,label:this.sinkLabel}};
          this.axios.post("api/app/add/sink",queryParams).then(result =>{
            this.$message({
              message: "添加成功",
              type: 'success'
            });
          }).catch(err=>{
            this.$message.error("添加出错:"+err);
          })
        }else if(this.addOrUpdateApp === 'update'){
          let params = {code:this.sinkCode,describeInfo:this.sinkDescribe,label:this.sinkLabel,id:this.appId};
          this.axios.post("api/app/update",params).then(result =>{
            if(result.data === "更新成功"){
              this.$message({
                message: "更新成功",
                type: 'success'
              });
            }else{
              this.$message.error("更新失败");
            }
          }).catch(error=>{
            this.$message.error("更新出错:"+error);
          })
        }
      },
      researchAppsByType(){
        if(this.appType === 'All Types'){
          this.axios.get("api/app/get/all/"+this.searchAppInput).then(result =>{
            this.appInfos = result.data;
          }).catch(err=>{
            this.$message.error("查询出错:"+err);
          })
        }else if(this.appType === 'Interface'){
          this.axios.get("api/app/get/interface/"+this.searchAppInput).then(result =>{
            this.appInfos = result.data;
          }).catch(err=>{
            this.$message.error("查询出错:"+err);
          })
        }else if(this.appType === 'Script'){
          this.axios.get("api/app/get/script/"+this.searchAppInput).then(result =>{
            this.appInfos = result.data;
          }).catch(err=>{
            this.$message.error("查询出错:"+err);
          })
        }else if(this.appType === 'Source'){
          this.axios.get("api/app/get/source/"+this.searchAppInput).then(result =>{
            this.appInfos = result.data;
          }).catch(err=>{
            this.$message.error("查询出错:"+err);
          })
        }else if(this.appType === 'Sink'){
          this.axios.get("api/app/get/sink/"+this.searchAppInput).then(result =>{
            this.appInfos = result.data;
          }).catch(err=>{
            this.$message.error("查询出错:"+err);
          })
        }
      },
		  findApps(){
		    this.axios.get("api/app/get/all").then(result =>{
          this.appInfos = result.data;
        }).catch(err=>{
          this.$message.error("查询出错:"+err);
        })
      },
      findServices(){
        this.axios.get("api/service/get").then(result =>{
          this.serviceInfos = result.data;
        }).catch(err=>{
          this.$message.error("查询出错:"+err);
        })
      },
      researchServiceByName(){
        this.axios.get("api/service/get/"+this.inputServiceName).then(result =>{
          this.serviceInfos = result.data;
        }).catch(err=>{
          this.$message.error("查询出错:"+err);
        })
      },
      addApps(){
        this.addOrUpdateApp = "add";
        this.showApps = false;
        this.showAppsDetail = true;
        this.showServiceDetail = false;
        this.showServiceList = false;
        this.scriptLabel='';
        this.scriptDescribe='';
        this.scriptCode='';
        this.scriptName='';
        this.sourceLabel='';
        this.sourceDescribe='';
        this.sourceCode='';
        this.sourceName='';
        this.sinkLabel='';
        this.sinkDescribe='';
        this.sinkCode='';
        this.sinkName='';
      },
      showRunTime(){
        this.showApps = false;
        this.showAppsDetail = false;
        this.showServiceDetail = false;
        this.showServiceList = false;
      },
      showAppPage(){
        this.showApps = true;
        this.showAppsDetail = false;
        this.showServiceDetail = false;
        this.showServiceList = false;
        this.findApps();
      },
		  showServiceListPage(){
        this.showApps = false;
        this.showAppsDetail = false;
        this.showServiceDetail = false;
        this.showServiceList = true;
        this.findServices();
        this.clear();
      },
      turnToCreateServicePage(){
        this.flowData={
          nodeList: [],
            linkList: [],
            attr: {
              name:''
          },
          config: {
            showGrid: true,
              showGridText: '隐藏网格',
              showGridIcon: 'eye'
          },
          status: flowConfig.flowStatus.CREATE,
            remarks: []
        };
        this.showApps = false;
        this.showAppsDetail = false;
        this.showServiceDetail = true;
        this.showServiceList = false;
        this.initNodeSelectArea();
        this.addOrUpdateService = "add";
      },
      findAllSources(){
        this.axios.get("api/app/get/source").then(result =>{
          this.alistSource =[];
          for(let i=0;i<result.data.length;i++){
            let obj ={};
            obj.type="start";
            obj.nodeName = result.data[i].name;
            obj.icon= "StartIcon";
            this.alistSource.push(obj);
          }
        }).catch(err=>{
          this.$message.error("查询出错:"+err);
        })
      },
      findAllFunctions(){
        this.axios.get("api/app/get/script").then(result =>{
          this.alistFunction = [];
          for(let i=0;i<result.data.length;i++){
            let obj ={};
            obj.type="freedom";
            obj.nodeName = result.data[i].name;
            obj.icon= "FreedomIcon";
            this.alistFunction.push(obj);
          }
        }).catch(err=>{
          this.$message.error("查询出错:"+err);
        })
      },
      findAllSinks(){
        this.axios.get("api/app/get/sink").then(result =>{
          this.alistSink =[];
          //this.alistSink = result.data;
          for(let i=0;i<result.data.length;i++){
            let obj ={};
            obj.type="end";
            obj.nodeName = result.data[i].name;
            obj.icon= "EndIcon";
            this.alistSink.push(obj);
          }
        }).catch(err=>{
          this.$message.error("查询出错:"+err);
        })
      },
      handleSizeChange(val) {
        console.log(`每页 ${val} 条`);
      },

			toggleNodeShow0 (flag) {
				if (!flag) {
					this.tag.toolShow = false;
				} else {
					this.tag.toolShow = true;
				}
			},
			toggleNodeShow1 (flag) {
				if (!flag) {
					this.tag.commonNodeShow = false;
				} else {
					this.tag.commonNodeShow = true;
				}
			},
			toggleNodeShow2 (flag) {
				if (!flag) {
					this.tag.highNodeShow = false;
				} else {
					this.tag.highNodeShow = true;
				}
			},
			toggleNodeShow3 (flag) {
				if (!flag) {
					this.tag.laneNodeShow = false;
				} else {
					this.tag.laneNodeShow = true;
				}
			},
			getBrowserType () {
				let userAgent = navigator.userAgent;
				let isOpera = userAgent.indexOf("Opera") > -1;
				if (isOpera) {
					return 1;
				};
				if (userAgent.indexOf("Firefox") > -1) {
					return 2;
				}
				if (userAgent.indexOf("Chrome") > -1) {
					return 3;
				}
				if (userAgent.indexOf("Safari") > -1) {
					return 4;
				}
				if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera) {
					alert('IE浏览器支持性较差，推荐使用Firefox或Chrome');
					return 5;
				}
				if (userAgent.indexOf("Trident") > -1) {
					alert('Edge浏览器支持性较差，推荐使用Firefox或Chrome');
					return 6;
				};
			},
			dealCompatibility () {
				const that = this;

				that.browserType = that.getBrowserType();
				if (that.browserType == 2) {
					flowConfig.shortcut.scaleContainer = {
						code: 16,
						codeName: 'SHIFT(chrome下为ALT)',
						shortcutName: '画布缩放',
					};
				}
			},
			initJsPlumb () {
				const that = this;

				that.plumb = jsPlumb.getInstance(flowConfig.jsPlumbInsConfig);

				that.plumb.bind('beforeDrop', function(info) {
					let sourceId = info.sourceId;
					let targetId = info.targetId;

					if (sourceId == targetId) return false;
					let filter = that.flowData.linkList.filter(link => (link.sourceId == sourceId && link.targetId == targetId));
					if (filter.length > 0) {
						that.$message.error('同方向的两节点连线只能有一条！');
						return false;
					}
					return true;
				});

				that.plumb.bind('connection', function(conn, e) {
					let connObj = conn.connection.canvas;
					let o = {}, id, label;
					if (that.flowData.status == flowConfig.flowStatus.CREATE || that.flowData.status == flowConfig.flowStatus.MODIFY) {
						id = 'link-' + ZFSN.getId();
						label = '';
					} else if (that.flowData.status == flowConfig.flowStatus.LOADING) {
						let l = that.flowData.linkList[that.flowData.linkList.length - 1];
						id = l.id;
						label = l.label;
					}
					connObj.id = id;
					o.type = 'link';
					o.id = id;
					o.sourceId = conn.sourceId;
					o.targetId = conn.targetId;
					o.label = label;
					o.cls = {
						linkType: flowConfig.jsPlumbInsConfig.Connector[0],
						linkColor: flowConfig.jsPlumbInsConfig.PaintStyle.stroke,
						linkThickness: flowConfig.jsPlumbInsConfig.PaintStyle.strokeWidth
					};
					$('#' + id).bind('contextmenu', function(e) {
						that.showLinkContextMenu(e);
						that.currentSelect = that.flowData.linkList.filter(l => l.id == id)[0];
					});
					$('#' + id).bind('click', function(e) {
						let event = window.event || e;
						event.stopPropagation();
						that.currentSelect = that.flowData.linkList.filter(l => l.id == id)[0];
					});
					if (that.flowData.status != flowConfig.flowStatus.LOADING) that.flowData.linkList.push(o);
				});

				that.plumb.importDefaults({
					ConnectionsDetachable: flowConfig.jsPlumbConfig.conn.isDetachable
				});
			},
			initNodeSelectArea () {
				$(document).ready(function() {
					$(".node-item").draggable({
						opacity: flowConfig.defaultStyle.dragOpacity,
						helper: 'clone',
						cursorAt: {
							top: 16,
							left: 60
						},
						containment: "window",
						revert: "invalid"
					});
				});
			},
			listenShortcut () {
				const that = this;
				document.onkeydown = function(e) {
					let event = window.event || e;

					if (!that.activeShortcut) return;
					let key = event.keyCode;

					switch (key) {
						case flowConfig.shortcut.multiple.code:
							that.$refs.flowArea.rectangleMultiple.flag = true;
							break;
						case flowConfig.shortcut.dragContainer.code:
							that.$refs.flowArea.container.dragFlag = true;
							break;
						case flowConfig.shortcut.scaleContainer.code:
							that.$refs.flowArea.container.scaleFlag = true;
							break;
						case flowConfig.shortcut.dragTool.code:
							that.selectTool('drag');
							break;
						case flowConfig.shortcut.connTool.code:
							that.selectTool('connection');
							break;
						case flowConfig.shortcut.zoomInTool.code:
							that.selectTool('zoom-in');
							break;
						case flowConfig.shortcut.zoomOutTool.code:
							that.selectTool('zoom-out');
							break;
						case 37:
							that.moveNode('left');
							break;
						case 38:
							that.moveNode('up');
							break;
						case 39:
							that.moveNode('right');
							break;
						case 40:
							that.moveNode('down');
							break;
					}

					if (event.ctrlKey) {
						if (event.altKey) {
							switch (key) {
								case flowConfig.shortcut.settingModal.code:
									that.setting();
									break;
								case flowConfig.shortcut.testModal.code:
									that.openTest();
									break;
							}
						}
					}
				}
				document.onkeyup = function(e) {
					let event = window.event || e;

					let key = event.keyCode;
					if (key == flowConfig.shortcut.dragContainer.code) {
						that.$refs.flowArea.container.dragFlag = false;
					} else if (key == flowConfig.shortcut.scaleContainer.code) {
						event.preventDefault();
						that.$refs.flowArea.container.scaleFlag = false;
					} else if (key == flowConfig.shortcut.multiple.code) {
						that.$refs.flowArea.rectangleMultiple.flag = false;
					}
				}

			},
			listenPage () {
				window.onbeforeunload = function (e) {
					e = e || window.event;
					if (e) {
						e.returnValue = '关闭提示';
					}
					return '关闭提示';
				};
			},
			initFlow () {
				const that = this;

				if (that.flowData.status == flowConfig.flowStatus.CREATE) {
					//that.flowData.attr.id = 'flow-' + ZFSN.getId();
				} else {
					that.loadFlow();
				}
			},
			loadFlow (json) {
				const that = this;

				that.clear();
				let loadData = JSON.parse(json);
				that.flowData.attr = loadData.attr;
				that.flowData.config = loadData.config;
				that.flowData.status = flowConfig.flowStatus.LOADING;
				that.plumb.batch(function() {
					let nodeList = loadData.nodeList;
					nodeList.forEach(function(node, index) {
						that.flowData.nodeList.push(node);
					});
					let linkList = loadData.linkList;
					that.$nextTick(() => {
						linkList.forEach(function(link, index) {
							that.flowData.linkList.push(link);
							let conn = that.plumb.connect({
								source: link.sourceId,
								target: link.targetId,
								anchor: flowConfig.jsPlumbConfig.anchor.default,
								connector: [
									link.cls.linkType,
									{
										gap: 5,
										cornerRadius: 8,
										alwaysRespectStubs: true
									}
								],
								paintStyle: {
									stroke: link.cls.linkColor,
									strokeWidth: link.cls.linkThickness
								}
							});
							if (link.label != '') {
								conn.setLabel({
									label: link.label,
									cssClass: 'linkLabel'
								});
							}
						});
						that.currentSelect = {};
						that.currentSelectGroup = [];
						that.flowData.status = flowConfig.flowStatus.MODIFY;
					});
				}, true);
				let canvasSize = that.computeCanvasSize();
				that.$refs.flowArea.container.pos = {
					top: -canvasSize.minY + 100,
					left: -canvasSize.minX + 100
				}
			},
			findNodeConfig (belongto, type, callback) {
				let node = null;
				switch (type) {
					case 'start':
					  for(let i=0;i<this.alistSource.length;i++){
					    if(belongto === this.alistSource[i].nodeName){
                node = this.alistSource[i];
              }
            }
						break;
					case 'freedom':
            for(let i=0;i<this.alistFunction.length;i++){
              if(belongto === this.alistFunction[i].nodeName){
                node = this.alistFunction[i];
              }
            }
						break;
					case 'end':
            for(let i=0;i<this.alistSink.length;i++){
              if(belongto === this.alistSink[i].nodeName){
                node = this.alistSink[i];
              }
            }
						break;
				}
				if (node && node.length >= 0) node = node[0];
				callback(node);
			},
			selectTool (type) {
				let tool = tools.filter(t => t.type == type);
				if (tool && tool.length >= 0) this.currentTool = tool[0];

				switch (type) {
					case 'drag':
						this.changeToDrag();
						break;
					case 'connection':
						this.changeToConnection();
						break;
					case 'zoom-in':
						this.changeToZoomIn();
						break;
					case 'zoom-out':
						this.changeToZoomOut();
						break;
				}
			},
			changeToDrag () {
				const that = this;

				that.flowData.nodeList.forEach(function(node, index) {
					let f = that.plumb.toggleDraggable(node.id);
					if (!f) {
						that.plumb.toggleDraggable(node.id);
					}
					if (node.type != 'x-lane' && node.type != 'y-lane') {
						that.plumb.unmakeSource(node.id);
						that.plumb.unmakeTarget(node.id);
					}
				});
			},
			changeToConnection() {
				const that = this;

				that.flowData.nodeList.forEach(function(node, index) {
					let f = that.plumb.toggleDraggable(node.id);
					if (f) {
						that.plumb.toggleDraggable(node.id);
					}
					if (node.type != 'x-lane' && node.type != 'y-lane') {
						that.plumb.makeSource(node.id, flowConfig.jsPlumbConfig.makeSourceConfig);
						that.plumb.makeTarget(node.id, flowConfig.jsPlumbConfig.makeTargetConfig);
					}
				});

				that.currentSelect = {};
				that.currentSelectGroup = [];
			},
			changeToZoomIn () {
				console.log('切换到放大工具');
			},
			changeToZoomOut () {
				console.log('切换到缩小工具');
			},
			checkFlow () {
				const that = this;
				let nodeList = that.flowData.nodeList;

				if (nodeList.length <= 0) {
					this.$message.error('流程图中无任何节点！');
					return false;
				}
				return true;
			},
			saveFlow () {
				const that = this;
				let flowObj = Object.assign({}, that.flowData);

				if (!that.checkFlow()) return;
				flowObj.status = flowConfig.flowStatus.SAVE;
				let d = JSON.stringify(flowObj);
        let json ={};
        if(this.addOrUpdateService === "add"){
          json ={param:{}};
          json.param.name = flowObj.attr.name;
          json.param.process =d;
          this.axios.post("api/service/add",json).then(result =>{
            this.$message.success("新增成功");
          }).catch(err=>{
            this.$message.error("新增出错:"+err);
          })
        }else if(this.addOrUpdateService === "update"){
          json.id = this.serviceId;
          //json.param.name = flowObj.attr.name;
          json.process =d;
          this.axios.post("api/service/update",json).then(result =>{
            this.$message.success("更新成功");
          }).catch(err=>{
            this.$message.error("更新出错:"+err);
          })
        }
				return d;
			},


			computeCanvasSize () {
				const that = this;
				let nodeList = Object.assign([], that.flowData.nodeList),
					minX = nodeList[0].x,
					minY = nodeList[0].y,
					maxX = nodeList[0].x + nodeList[0].width,
					maxY = nodeList[0].y + nodeList[0].height;
				nodeList.forEach(function(node, index) {
					minX = Math.min(minX, node.x);
					minY = Math.min(minY, node.y);
					maxX = Math.max(maxX, node.x + node.width);
					maxY = Math.max(maxY, node.y + node.height);
				});
				let canvasWidth = maxX - minX;
				let canvasHeight = maxY - minY;
				return {
					width: canvasWidth,
					height: canvasHeight,
					minX: minX,
					minY: minY,
					maxX: maxX,
					maxY: maxY
				};
			},
			clear () {
				const that = this;
				that.flowData.nodeList.forEach(function(node, index) {
					that.plumb.remove(node.id);
				});
				that.currentSelect = {};
				that.currentSelectGroup = [];
				that.flowData.nodeList = [];
				that.flowData.linkList = [];
				that.flowData.remarks = [];
			},
			toggleShowGrid () {
				let flag = this.flowData.config.showGrid;
				if (flag) {
					this.flowData.config.showGrid = false;
					this.flowData.config.showGridText = '显示网格';
					this.flowData.config.showGridIcon = 'eye-invisible';
				} else {
					this.flowData.config.showGrid = true;
					this.flowData.config.showGridText = '隐藏网格';
					this.flowData.config.showGridIcon = 'eye';
				}
			},
			setting () {
				this.$refs.settingModal.open();
			},
			shortcutHelper () {
				this.$refs.shortcutModal.open();
			},
			exit () {
				alert('退出流程设计器...');
			},
			showLinkContextMenu (e) {
				let event = window.event || e;

				event.preventDefault();
				event.stopPropagation();
				$('.vue-contextmenuName-flow-menu').css('display', 'none');
				$('.vue-contextmenuName-node-menu').css('display', 'none');
				let x = event.clientX;
				let y = event.clientY;
				this.linkContextMenuData.axis = { x, y };
			},
			deleteLink () {
				const that = this;
				let sourceId = that.currentSelect.sourceId;
				let targetId = that.currentSelect.targetId;
				that.plumb.deleteConnection(that.plumb.getConnections({
					source: sourceId,
					target: targetId
				})[0]);
				let linkList = that.flowData.linkList;
				linkList.splice(linkList.findIndex(link => (link.sourceId == sourceId || link.targetId == targetId)), 1);
				that.currentSelect = {};
			},
			loseShortcut () {
				this.activeShortcut = false;
			},
			getShortcut () {
				this.activeShortcut = true;
			},
			openTest () {
				const that = this;

				let flowObj = Object.assign({}, that.flowData);
				that.$refs.testModal.flowData = flowObj;
				that.$refs.testModal.testVisible = true;
			},
			moveNode (type) {
				const that = this;

				let m = flowConfig.defaultStyle.movePx, isX = true;
				switch (type) {
					case 'left':
						m = -m;
						break;
					case 'up':
						m = -m;
						isX = false;
						break;
					case 'right':
						break;
					case 'down':
						isX = false;
				}

				if (that.currentSelectGroup.length > 0) {
					that.currentSelectGroup.forEach(function(node, index) {
						if (isX) {
							node.x += m;
						} else {
							node.y += m;
						}
					});
					that.plumb.repaintEverything();
				} else if (that.currentSelect.id) {
					if (isX) {
						that.currentSelect.x += m;
					} else {
						that.currentSelect.y += m;
					}
					that.plumb.repaintEverything();
				}
			},
		}
	}
</script>

<style lang="scss">
	@import './style/flow-designer.scss';
  .el-card__body{
    padding: 0px;
  }
</style>
